/**
 * 被动事件监听器工具函数
 * 用于优化滚动性能，消除浏览器关于非被动事件监听器的警告
 */

// 需要设置为被动的事件类型
const PASSIVE_EVENTS = [
  'wheel',
  'mousewheel',
  'touchstart',
  'touchmove',
  'touchend',
  'touchcancel'
] as const

type PassiveEvent = typeof PASSIVE_EVENTS[number]

// 检查浏览器是否支持被动事件监听器
let supportsPassive = false
try {
  const opts = Object.defineProperty({}, 'passive', {
    get() {
      supportsPassive = true
      return true
    }
  })
  window.addEventListener('testPassive', null as any, opts)
  window.removeEventListener('testPassive', null as any, opts)
} catch (e) {
  // 浏览器不支持被动事件监听器
}

/**
 * 为指定事件类型设置被动监听器
 * @param eventType 事件类型
 * @returns 事件选项对象
 */
export function getPassiveEventOptions(eventType: string): boolean | AddEventListenerOptions {
  if (!supportsPassive) {
    return false
  }
  
  const isPassiveEvent = PASSIVE_EVENTS.includes(eventType as PassiveEvent)
  return isPassiveEvent ? { passive: true } : false
}

/**
 * 添加被动事件监听器
 * @param element 目标元素
 * @param eventType 事件类型
 * @param handler 事件处理函数
 * @param options 额外选项
 */
export function addPassiveEventListener(
  element: Element | Window | Document,
  eventType: string,
  handler: EventListener,
  options: AddEventListenerOptions = {}
): void {
  const passiveOptions = getPassiveEventOptions(eventType)
  const finalOptions = typeof passiveOptions === 'object' 
    ? { ...passiveOptions, ...options }
    : options
    
  element.addEventListener(eventType, handler, finalOptions)
}

/**
 * 移除事件监听器
 * @param element 目标元素
 * @param eventType 事件类型
 * @param handler 事件处理函数
 * @param options 选项
 */
export function removePassiveEventListener(
  element: Element | Window | Document,
  eventType: string,
  handler: EventListener,
  options: EventListenerOptions = {}
): void {
  element.removeEventListener(eventType, handler, options)
}

/**
 * 全局设置被动事件监听器
 * 重写原生的 addEventListener 方法，自动为滚动相关事件添加被动选项
 */
export function setupGlobalPassiveEvents(): void {
  if (!supportsPassive) {
    return
  }

  // 保存原始的 addEventListener 方法
  const originalAddEventListener = EventTarget.prototype.addEventListener
  const originalRemoveEventListener = EventTarget.prototype.removeEventListener

  // 重写 addEventListener 方法
  EventTarget.prototype.addEventListener = function(
    type: string,
    listener: EventListenerOrEventListenerObject | null,
    options?: boolean | AddEventListenerOptions
  ) {
    let finalOptions = options

    // 如果是滚动相关事件且没有明确指定 passive 选项
    if (PASSIVE_EVENTS.includes(type as PassiveEvent)) {
      if (typeof options === 'boolean') {
        // 如果 options 是布尔值，转换为对象格式
        finalOptions = { capture: options, passive: true }
      } else if (typeof options === 'object' && options !== null) {
        // 如果已经是对象，添加 passive 属性（如果未设置）
        if (!('passive' in options)) {
          finalOptions = { ...options, passive: true }
        }
      } else {
        // 如果没有提供 options，设置为被动
        finalOptions = { passive: true }
      }
    }

    return originalAddEventListener.call(this, type, listener, finalOptions)
  }

  // 保持 removeEventListener 的原始行为
  EventTarget.prototype.removeEventListener = originalRemoveEventListener

  console.log('✅ 全局被动事件监听器已设置')
}

/**
 * 恢复原始的事件监听器方法
 */
export function restoreOriginalEventListeners(): void {
  // 这个函数可以用于测试或特殊情况下恢复原始行为
  // 实际项目中通常不需要调用
}

export default {
  setupGlobalPassiveEvents,
  addPassiveEventListener,
  removePassiveEventListener,
  getPassiveEventOptions,
  supportsPassive
}